package edu.uwm.cs552;

/**
 * Default construction cost.
 * Assuming track is legal (not BLOCKed and not within a large city or into water),
 * then we charge 1 for the track itself, one extra for mountains
 * (twice if between two mountains), two extra for crossing rivers or entering
 * small or medium cities, and four extra for crossing an inlet.
 */
public class DefaultConstructionCost implements ConstructionCost {

	private static ConstructionCost instance;
	
	/**
	 * Return the singleton instance of this class.
	 * @return
	 */
	public static ConstructionCost getInstance() {
		if (instance == null) instance = new DefaultConstructionCost();
		return instance;
	}
	
	private DefaultConstructionCost() {}
	
	private double barrierCost(Barrier b) {
		if (b == null) return 0.0;
		switch (b) {
		case BLOCK:
			return Double.POSITIVE_INFINITY;
		case INLET:
			return 4.0;
		case RIVER:
		case DRAWN:
			return 2.0;
		}
		return Double.POSITIVE_INFINITY;
	}
	
	private double terrainCost(Terrain t) {
		if (t == null) return Double.POSITIVE_INFINITY;
		switch (t) {
		case SUBURB:
		case PLAIN: return 0.0;
		case DESERT: return 0.0;
		case MOUNTAIN: return 1.0;
		case SMALL:
		case MEDIUM: return 2.0;
		case LARGE:
		case WATER: return Double.POSITIVE_INFINITY;
		}
		return Double.POSITIVE_INFINITY;
	}
	
	public double cost(Terrain t1, Barrier b, Terrain t2) {
		// special case: not allowed to build between two suburbs,
		// because we assume they are for the same city.
		if (t1 == Terrain.SUBURB && t2 == Terrain.SUBURB) return Double.POSITIVE_INFINITY;
		return 1 + terrainCost(t1) + barrierCost(b) + terrainCost(t2);
	}

}
